#include "Vector3.h"


namespace lib3dw
{
	void Vector3::operator += (const float s)
	{
		x += s;
		y += s;
		z += s;
	}

	void Vector3::operator += (const Vector3 &v)
	{
		x += v.x;
		y += v.y;
		z += v.z;
	}

	void Vector3::operator -= (const float s)
	{
		x -= s;
		y -= s;
		z -= s;
	}

	void Vector3::operator -= (const Vector3 &v)
	{
		x -= v.x;
		y -= v.y;
		z -= v.z;
	}

	void Vector3::operator *= (const float s)
	{
		x *= s;
		y *= s;
		z *= s;
	}

	void Vector3::operator *= (const Vector3 &v)
	{
		x *= v.x;
		y *= v.y;
		z *= v.z;
	}

	void Vector3::operator /= (const float s)
	{
		x /= s;
		y /= s;
		z /= s;
	}

	void Vector3::operator /= (const Vector3 &v)
	{
		x /= v.x;
		y /= v.y;
		z /= v.z;
	}

	Vector3& Vector3::cross(const Vector3& v)
	{
		float newx = y*v.z - z*v.y;
		float newy = z*v.x - x*v.z;
		float newz = x*v.y - y*v.x;

		x = newx;
		y = newy;
		z = newz;

		return *this;
	}

	Vector3& Vector3::normalize()
	{
		float len = sqrt(x*x + y*y + z*z);
		if (len != 0) 
		{
			x /= len;
			y /= len;
			z /= len;
		}

		return *this;
	}

	Vector3& Vector3::flip()
	{
		x = -x;
		y = -y;
		z = -z;
		return *this;
	}

	float Vector3::length() const
	{
		return (sqrt(x*x + y*y + z*z));
	}

	float Vector3::dot(Vector3 &u)
	{
		return x * u.x + y * u.y + z * u.z;
	}

	Vector3 operator + (const Vector3 &u, const Vector3 &v)
	{
		return Vector3(u.x + v.x, u.y + v.y, u.z + v.z);
	}

	Vector3 operator + (const Vector3 &v, const float s)
	{
		return Vector3(v.x + s, v.y + s, v.z + s);
	}

	Vector3 operator + (const float s, const Vector3 &v)
	{
		return Vector3(v.x + s, v.y + s, v.z + s);
	}

	Vector3 operator - (const Vector3 &u, const Vector3 &v)
	{
		return Vector3(u.x - v.x, u.y - v.y, u.z - v.z);
	}

	Vector3 operator - (const Vector3 &v, const float s)
	{
		return Vector3(v.x - s, v.y - s, v.z - s);
	}

	Vector3 operator - (const float s, const Vector3 &v)
	{
		return Vector3(v.x - s, v.y - s, v.z - s);
	}

	Vector3 operator - (const Vector3 &v)
	{
		return Vector3(-v.x, -v.y, -v.z);
	}

	Vector3 operator * (const Vector3 &u, const Vector3 &v)
	{
		return Vector3(u.x * v.x, u.y * v.y, u.z * v.z);
	}

	Vector3 operator * (const float s, const Vector3 &v)
	{
		return Vector3(v.x * s, v.y * s, v.z * s);
	}

	Vector3 operator * (const Vector3 &v, const float s)
	{
		return Vector3(v.x * s, v.y * s, v.z * s);
	}

	Vector3 operator / (const Vector3 &u, const Vector3 &v)
	{
		return Vector3(u.x / v.x, u.y / v.y, u.z / v.z);
	}

	Vector3 operator / (const Vector3 &v, const float s)
	{
		return Vector3(v.x / s, v.y / s, v.z / s);
	}

	Vector3 operator / (const float s, const Vector3 &v)
	{
		return Vector3(s / v.x, s / v.y, s / v.z);
	}

	bool operator == (const Vector3 &u, const Vector3 &v)
	{
		return (u.x == v.x && u.y == v.y && u.z == v.z);
	}
	
	float dot(const Vector3 &u, const Vector3 &v)
	{
		return u.x * v.x + u.y * v.y + u.z * v.z;
	}
	
	Vector3 cross(const Vector3 &u, const Vector3 &v)
	{
		float newx = u.y*v.z - u.z*v.y;
		float newy = u.z*v.x - u.x*v.z;
		float newz = u.x*v.y - u.y*v.x;

		return  Vector3(newx, newy, newz);
	}
}